﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Collections;

namespace Ict.DataAccess.Linq
{
    public abstract class Modifiable : IQueryable
    {
        private ModifiableProvider provider = null;

        protected SelectableBase query = null;

        protected Expression selectClause;

        protected List<Expression> whereClause = null;

        internal List<Expression> WhereClause
        {
            get
            {
                if (whereClause == null)
                    whereClause = new List<Expression>();
                return whereClause;
            }
            set
            {
                whereClause = value;
            }
        }

        protected string MapTableAlias<TElement>()
        {
            string result = null;
            if (query != null)
            {
                Expression exp = query.SelectClause;
                if (exp is LambdaExpression)
                {
                    exp = (exp as LambdaExpression).Body;
                    if (exp is MemberExpression)
                    {
                        result = (exp as MemberExpression).Member.Name;
                    }
                }
            }
            if (result == null)
            {
                result = TableMapper<TElement>.TableName;
            }
            return result;
        }

        protected void BuildCondition<TElement>(StringBuilder stringBuilder, List<Expression> whereClause)
        {
            if (query == null)
            {
                query = DataContext.Select<TElement>();
                query.WhereClause = whereClause;
            }

            query.BuildCondition(stringBuilder);
        }

        internal abstract void AddExpression(string methodName, Expression expression);

        internal abstract Modifiable Clone<TElement>();

        internal abstract Modifiable Clone();

        #region IEnumerable 成员

        public IEnumerator GetEnumerator()
        {
            throw new NotSupportedException("仅供修改数据库中数据使用，不支持查询");
        }

        #endregion

        #region IEnumerable 成员

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        #endregion

        #region IQueryable 成员

        public abstract Type ElementType
        {
            get;
        }

        public System.Linq.Expressions.Expression Expression
        {
            get { return System.Linq.Expressions.Expression.Constant(this); }
        }

        public IQueryProvider Provider
        {
            get 
            {
                if (provider == null)
                {
                    provider = new ModifiableProvider();
                }
                return provider;
            }
            set
            {
                provider = value as ModifiableProvider;
            }
        }

        #endregion
    }
}
